#pragma once
#include "Connection.h"
#include "log.hpp"
#include<mysql.h>


Connection::Connection() 
{
	_connection = mysql_init(nullptr);
	if (_connection == nullptr)
	{
		LOG(WARMING, "MySQL连接建立失败");
	}
}

Connection::~Connection()
{
	if (_connection != nullptr)
		mysql_close(_connection);
}

void Connection::refreshAliveTime()
{
	_alivetime = clock();
}

clock_t Connection::getAliveTime() const
{
	return clock() - _alivetime;
}

bool Connection::connect(string ip, unsigned short port, string user, string password, string dbname)
{
	return nullptr != mysql_real_connect(_connection, ip.c_str(), user.c_str(), \
		password.c_str(), dbname.c_str(),port, nullptr, 0);
}

bool Connection::update(string sql)
{
	if (mysql_query(_connection, sql.c_str()) != 0)
	{
		LOG(ERROR, "sql语句执行失败" + sql);
		return false;
	}
	LOG(NORMAL, "sql语句执行成功" + sql);
	return true;
}

bool Connection::query(string sql)
{
	if (mysql_query(_connection, sql.c_str()) != 0)
	{
		LOG(ERROR, "sql语句执行失败" + sql);
		return false;
	}

	MYSQL_RES* res = mysql_store_result(_connection);//获取执行结果
	//解析数据 -- 获取行数和列数
	int rows = mysql_num_rows(res); // 获取行数
	int cols = mysql_num_fields(res);// 获取列数

	// 解析数据 -- 获取表中列名 -- 一般不用，仅仅是为了测试代码的完整性
	MYSQL_FIELD* fields = mysql_fetch_field(res);
	for (int i = 0; i < cols; i++)
	{
		std::cout << fields[i].name << "\t"; // 输出列名，通常没什么用
	}
	std::cout << std::endl;

	 //解析数据 -- 获取表中的数据 -- 重要
	for (int i = 0; i < rows; i++)
	{
		//获取完整的一行记录[可能包含了多列]
		MYSQL_ROW line = mysql_fetch_row(res);//MYSQL_ROW本质就是二级指针char**
		for (int j = 0; j < cols; j++)
		{
			std::cout << line[j] << "\t";//将记录内部的多列字符串依次打印！
		}
		std::cout << std::endl;
	}
	LOG(NORMAL, "SQL语句执行成功" + sql);
	return true;
}
